//希望是一个工具模块当中重写的以下方法
//希望在原型上拓展call/apply/bind方法
const utilsModule = (function (Function) {
  //外面注入的Function作为局部变量

  //ctx -> 执行期上下文
  //ctx 必须是一个引用值对象
  //说明只有函数(对象不行)才能调用myBind方法
  Function.prototype.myBind = function (ctx) {
    // console.log(ctx);
    //执行期上下文：{a: 1, b: 2}

    // console.log(this);
    //ƒ test(user, car) {...}

    //保存原函数
    var originFn = this,
      //bind传递的参数列表
      //test.myBind(obj1, 'rose', 'jack')
      //截取范围: 1 - 最后
      args = [].slice.call(arguments, 1),
      //圣杯模式
      _temFn = function () {};

    // console.log(args);
    //['rose', 'jack']

    var newFn = function () {
      //返回新函数的参数列表
      //test('rose', 'jack')
      var newArgs = [].slice.call(arguments);
      // console.log(arguments); Arguments []
      // console.log(newArgs); []

      return originFn.apply(
        //如果新的实例对象是newFn构造出来时
        //是：this指向当前this
        //否：this就为ctx执行期上下文
        this instanceof newFn ? this : ctx,
        //合并两参数列表返回新的参数列表数组
        args.concat(newArgs)
      );
    };

    //实例应该继承构造函数上的原型属性
    _temFn.prototype = this.prototype;
    newFn.prototype = new _temFn();

    return newFn;
  };
})(Function);

export default utilsModule;
